﻿using System;
using EnvDTE;
using EnvDTE80;
using System.Windows.Forms;
using System.Collections.Generic;
using ImaginarTI.RealFolders.Menu;

namespace ImaginarTI.RealFolders
{
    class ProjectMenu
    {
        /// <summary>
        /// STATIC List containing Menu items AND asscociated Commands
        /// </summary>
        private static Dictionary<string, VSCommandInfo> CommandDescriptionList = new Dictionary<string, VSCommandInfo>();

        /// <summary>
        /// Visual Studio instance
        /// </summary>
        public DTE2 VStudioApplication { get; set; }
        
        /// <summary>
        /// AddIn instance
        /// </summary>
        public AddIn AddInInstance { get; set; }

        public enum VStudioCSharpProjectType { Unknown = 0, WinFormConsole, WebApplication, MVCApplication, WebSite };

        public class ProjectType
        {
            public string Name { get; set; }
            public string Id { get; set; }
            public VStudioCSharpProjectType VSType { get; set; }
            public string ResourceFolder { get; set; }
        }
        
        public ProjectMenu(MenuParams _params)
        {
        }

        /// <summary>
        /// Elimina todos os comandos da lista
        /// </summary>
        protected void ClearCommands(object owner)
        {
            foreach (KeyValuePair<string, VSCommandInfo> kvp in CommandDescriptionList)
            {
                VSCommandInfo desc = kvp.Value;
                if (desc.Owner == owner || desc.Owner == null)
                    CommandDescriptionList.Remove(kvp.Key);
            }

        }

        /// <summary>
        /// Add a command object to our command list
        /// </summary>
        /// <param name="item">the menu we want to add</param>
        protected void AddCommand(VSCommandInfo item)
        {
            string cmdId = AddInInstance.ProgID + "." + item.Name;
            if (!CommandDescriptionList.ContainsKey(cmdId))
            {
                item.UniqueID = cmdId;
                CommandDescriptionList.Add(cmdId, item);
            }
            else
                MessageBox.Show(cmdId + " already exists in this plugin !", "Error : " + AddInInstance.ProgID, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        /// <summary>
        /// Cria os comandos específicos para o Plugin
        /// </summary>
        public void CreateCommands()
        {
            // first clear list
            ClearCommands(this);

            // add commands individually
            AddCommand(new VSCommandInfo()
            {
                Name = "NEW",
                Owner = this,
                HaveSeparator = false,
                Caption = "New",
                Position = 1,
                ToolTip = "",
                BitmapResourceId = 2,
                UseOfficeResources = false,
                Action = new PerformActionForVSCommandDelegate(RunCommand_New)
            });

            AddCommand(new VSCommandInfo()
            {
                Name = "EDIT",
                Owner = this,
                HaveSeparator = false,
                Caption = "Edit",
                Position = 2,
                ToolTip = "",
                BitmapResourceId = 59,
                UseOfficeResources = true

            });
        }


        /// <summary>
        /// Code associated with command "NEW"
        /// </summary>
        private void RunCommand_New()
        {
            // do what you want after running custom actions
            bool bSolutionLoaded = isSolutionLoaded(VStudioApplication);
            if (bSolutionLoaded)
            {
                ProjectType pfound = null;
                EnvDTE.Project p = getActiveProject(VStudioApplication);
                if (p != null)
                {
                    if (isSupportedProject(p, out pfound))
                    {
                        MessageBox.Show("NEW");
                    }
                    else
                        MessageBox.Show("Unsupported Project !");
                }
                else
                    MessageBox.Show("No project loaded !");
            }
            else
                MessageBox.Show("No Solution loaded !");
        }


        private static bool isSolutionLoaded(DTE2 _applicationObject)
        {
            bool ret = false;
            if (_applicationObject != null && _applicationObject.Solution != null)
            {
                ret = true;
            }
            return ret;
        }
        private static EnvDTE.Project getActiveProject(DTE2 _applicationObject)
        {
            EnvDTE.Project p = null;
            if (isSolutionLoaded(_applicationObject))
            {
                Array projectArray = null;
                try
                {
                    projectArray = (Array)_applicationObject.ActiveSolutionProjects;
                    if (projectArray != null && projectArray.Length > 0)
                        p = (EnvDTE.Project)projectArray.GetValue(0);
                }
                catch
                {
                }
            }
            return p;
        }
        public static bool isSupportedProject(EnvDTE.Project p, out ProjectType ProjectTypeFound)
        {
            bool ret = false;
            ProjectTypeFound = null;
            if (p == null) return ret;
            List<string> languages = getSupportedCodeModels();
            if (p.CodeModel.Language != null && languages.IndexOf(p.CodeModel.Language) >= 0)
            {
                string projectType = p.Kind;
                if (!String.IsNullOrEmpty(projectType))
                {
                    string[] types = projectType.Split(new char[] { ';' });
                    if (types.Length == 0) types = new string[1] { projectType };

                    List<ProjectType> support = GetSupportedProjectTypes();
                    for (int i = 0; i < types.Length; i++)
                    {
                        ProjectType found = support.Find(
                             delegate(ProjectType inP) { return (String.Compare(inP.Id, types[i], true) == 0); }
                           );
                        if (found != null)
                        {
                            ProjectTypeFound = found;
                            ret = true;
                            break;
                        }
                    }
                }
            }

            return ret;
        }
        public static List<string> getSupportedCodeModels()
        {
            List<string> tmp = new List<string>();
            tmp.Add(EnvDTE.CodeModelLanguageConstants.vsCMLanguageCSharp);
            return tmp;
        }
        public static List<ProjectType> GetSupportedProjectTypes()
        {
            List<ProjectType> tmp = new List<ProjectType>();
            tmp.Add(new ProjectType() { VSType = VStudioCSharpProjectType.WinFormConsole, Name = "C# Winform / Console ", Id = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", ResourceFolder = "Properties" });
            tmp.Add(new ProjectType() { VSType = VStudioCSharpProjectType.WebApplication, Name = "C# Web Application Project Templates", Id = "{349C5853-65DF-11DA-9384-00065B846F21}", ResourceFolder = "App_GlobalResources" });
            tmp.Add(new ProjectType() { VSType = VStudioCSharpProjectType.MVCApplication, Name = "C# Web MVC Project Templates", Id = "{603c0e0c-db56-11dc-be95-000d561079b0}", ResourceFolder = "App_GlobalResources" });
            tmp.Add(new ProjectType() { VSType = VStudioCSharpProjectType.WebSite, Name = "Web Site", Id = "{E24C65DC-7377-472B-9ABA-BC803B73C61A}", ResourceFolder = "" });
            return tmp;
        }

    }
}
